using CfgTable;
using IQIGame.Onigao.Framework;
using IQIGame.Onigao.Game;
using NetProtocol.Client;
using NetProtocol.Enum;
using NetProtocol.POD;
using System.Collections.Generic;

namespace IQIGame.Onigao.GamePlay
{
    /// <summary>
    /// 类名 : 模块 - 任务
    /// 作者 : Canyon / 龚阳辉
    /// 日期 : 2024-07-09 10:02
    /// 功能 : 
    /// </summary>
    public class QuestModule : Singleton<QuestModule>, CNetQuest
    {
        public int collectionQuestCid
        {
            get
            {
                if (_collectionQuestCid != 0)
                {
                    return _collectionQuestCid;
                }
                
                var configList = TableCenter.quest.DataList;
                for (var i = 0; i < configList.Count; i++)
                {
                    if (configList[i].Type != QuestType.Achieve) continue;
                    _collectionQuestCid = configList[i].Id;
                    return configList[i].Id;
                }
                
                LogGame.LogError($"No quest use type {QuestType.Achieve}");
                return 0;
            }
        }
        private QuestModule() { }
        private QuestModuleData quest => GameDataCenter.PlayerData.quest;

        private int _collectionQuestCid;
        public void InitModule(PlayerPOD playerPOD)
        {
            QuestModuleData data = new QuestModuleData(playerPOD.quests, playerPOD.committedQuestList, playerPOD.failQuestList, playerPOD.trackQuestCid);
            GameDataCenter.PlayerData.quest = data;
            foreach (var pod in playerPOD.quests)
            {
                PODPool<QuestPOD>.Put(pod);
            }
            playerPOD.quests.Clear();
        }

        public void ClearModule()
        {
            var data = GameDataCenter.PlayerData.quest;
            GameDataCenter.PlayerData.quest = null;
            data?.Clear();
        }

        #region Net层
        public static CNetQuest NetCore => Instance;

        ISession CNetQuest.GetSession()
        {
            return GameServerModule.Instance.CurrSession;
        }

        void CNetQuest.SC_notifyAcceptQuest(ISession session, List<QuestPOD> questList)
        {
            foreach (QuestPOD questPOD in questList)
            {
                this.ChangeData(questPOD);
                PODPool<QuestPOD>.Put(questPOD);
            }
            MsgDispatcher.Broadcast(MsgEventType.QuestAdd);
        }

        void CNetQuest.SC_notifyUpdateQuest(ISession session, QuestPOD questPOD)
        {
            this.ChangeData(questPOD);
            PODPool<QuestPOD>.Put(questPOD);
        }

        void CNetQuest.SC_notifyCommitQuest(ISession session, List<int> cids, List<ItemShowPOD> awards, QuestCommitOp op)
        {
            switch (op)
            {
                case QuestCommitOp.CSingle:
                    UD_QuestGet data = UD_QuestGet.NewFromPool().Sync(cids[0], awards);
                    ManagerCenter.UI.ShowWindow<UIQuestGet>(data);
                    break;
                case QuestCommitOp.CBatch:
                    NoticeModule.ShowUIItemGet(awards);
                    break;
                default:
                    break;
            }
        }

        void CNetQuest.SC_notifyRemoveQuest(ISession session, List<int> cids)
        {
            foreach (int cid in cids)
            {
                this.quest.Remove(cid);
            }
            MsgDispatcher.Broadcast(MsgEventType.QuestRemove);
        }

        void CNetQuest.SC_notifyCommittedQuestList(ISession session, List<int> cids, bool remove)
        {
            foreach (int cid in cids)
            {
                if (remove)
                {
                    this.quest.RemoveSuccess(cid);
                }
                else
                {
                    this.quest.AddSuccess(cid);
                }
            }
        }

        void CNetQuest.SC_notifyFailQuestList(ISession session, List<int> cids, bool remove)
        {
            foreach (int cid in cids)
            {
                if (remove)
                {
                    this.quest.RemoveFail(cid);
                }
                else
                {
                    this.quest.AddFail(cid);
                }
            }
        }

        void CNetQuest.SC_notifyTrackQuest(ISession session, int cid)
        {
            this.quest.UpdateTrackQuest(cid);
            MsgDispatcher.Broadcast<int>(MsgEventType.QuestStartTrack, cid);
        }
        #endregion


        protected void ChangeData(QuestPOD pod)
        {
            var cfgOne = TableCenter.quest.Get(pod.cid);
            if (cfgOne == null)
                return;
            if (this.quest.TryGetValue(pod.cid, out var dCahce))
            {
                dCahce.Sync(pod);
            }
            else
            {
                this.quest.Add(QuestData.ConvertFromPOD(pod));
            }
        }

        #region 条件判断
        /// <summary>
        /// 任务是否可以接取
        /// </summary>
        public bool IsAcceptable(int questCid, TViewEntity curEntity = null)
        {
            if (quest.IsInSuccess(questCid)
                || quest.IsInFail(questCid)
                || quest.ContainsKey(questCid))
            {
                return false;
            }

            CfgQuest cfg = TableCenter.quest.Get(questCid);
            if (cfg == null) return false;
            if (!cfg.ManualAcceptable) return false;
            // TODO 测试功能开启
            if (cfg.FunctionOpen > 0)
            {
                return false;
            }
            if (cfg.PreQuest > 0 && !quest.IsInSuccess(cfg.PreQuest))
            {
                return false;
            }
            if (!(GameplayAreaManager.Instance.curArea is IGameplaySceneArea sceneArea))
            {
                LogGame.LogError($"当前模块{GameplayAreaManager.Instance.curArea.areaType}不支持条件判断");
                return false;
            }
            (bool isOK, int failId) = sceneArea.CheckCondition(cfg.ManualCondition, curEntity);
            return isOK;
        }
        #endregion
    }
}
